package com.niiwoo.civet.trade.service.local.contract;

import com.alibaba.dubbo.config.annotation.Reference;
import com.niiwoo.civet.account.service.AccountCompanyDubboService;
import com.niiwoo.civet.trade.dao.entity.CreditorSaleDetail;
import com.niiwoo.civet.trade.dao.entity.FadadaContractTemplateFile;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dao.entity.ProjectContract;
import com.niiwoo.civet.trade.dao.mapper.FadadaContractTemplateFileMapperExt;
import com.niiwoo.civet.trade.dto.response.CreditorTransferProtocolPreviewResponseDTO;
import com.niiwoo.civet.trade.enums.FadadaContractTemplateEnum;
import com.niiwoo.civet.trade.service.local.invest.InvestService;
import com.niiwoo.civet.user.dto.response.UserAuthorizationInfoResponseDTO;
import com.niiwoo.civet.user.service.UserAuthorizationInfoDubboService;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO;
import com.niiwoo.tripod.fadada.dto.request.GenerateContractRequestDTO.DynamicTable;
import com.niiwoo.tripod.fadada.dto.response.FadadaResponseDTO;
import com.niiwoo.tripod.fadada.enums.SignClientRoleEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 债权转让协议
 * Created by HuangMin on 2018/7/12.
 */
@Service
public class CreditorTransferContract extends AbstractFadadaContract {

    private static final Logger logger = LoggerFactory.getLogger(CreditorTransferContract.class);

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private FadadaContractTemplateFileMapperExt contractTemplateFileMapperExt;
    @Autowired
    private InvestService investService;

    @Reference(version = "1.0.0")
    private AccountCompanyDubboService accountCompanyDubboService;
    @Reference(version = "1.0.0")
    private UserAuthorizationInfoDubboService userAuthorizationInfoDubboService;

    @Value("${platform.caCertId}")
    private String platformCaCertId;


    @Override
    public ProjectContract contractHandler(FadadaContractTemplateFile contractTemplate, String bizContractNo,
                                           Project project, String userId) throws Exception {
        return null;
    }

    public ProjectContract contractHandler(FadadaContractTemplateEnum.TemplateTypeEnum templateType,
                                           String investorUserId, CreditorSaleDetail creditorSaleDetail) throws Exception {
        FadadaContractTemplateFile contractTemplateFile = contractTemplateFileMapperExt.queryFadadaContractTemplateFileByTemplateType(templateType.getType());
        if (contractTemplateFile == null) {
            // 借款合同模板不存在
            throw new BizException("TRD_700007", templateType + " templateType not exists.");
        }
        logger.info("债权转让协议处理开始... creditorSaleDetailId:{}", creditorSaleDetail.getId());
        String contractId = snowflakeIdWorker.nextId() + "";

        CreditorTransferProtocolPreviewResponseDTO transfer = investService.creditorTransferProtocolPreview(creditorSaleDetail.getId(), creditorSaleDetail.getUserId(), investorUserId);

        this.generateContract(contractTemplateFile, contractId, creditorSaleDetail, transfer);

        ProjectContract result = this.signContract(contractId, creditorSaleDetail, investorUserId, transfer, contractTemplateFile);

        this.contractFilling(contractId);
        logger.info("债权转让协议处理结束... creditorSaleDetailId:{}", creditorSaleDetail.getId());
        return result;
    }

    private void generateContract(FadadaContractTemplateFile contractTemplate, String contractId,
                                  CreditorSaleDetail creditorSaleDetail, CreditorTransferProtocolPreviewResponseDTO transfer) throws Exception {
        logger.info("债权转让协议生成开始... creditorSaleDetailId:{}", creditorSaleDetail.getId());

        GenerateContractRequestDTO dto = new GenerateContractRequestDTO();
        dto.setContractId(contractId);
        dto.setDocTitle(contractTemplate.getTemplateName());
        dto.setTemplateId(contractTemplate.getTemplateId());

        Map<String, String> parameterMap = new HashMap<String, String>();

        parameterMap.put("protocolNo", transfer.getProtocolNo());                                           //协议编号
        parameterMap.put("niiwooReditCode", transfer.getNiiwooReditCode());                                 //(丙方)营业执照编号
        //parameterMap.put("niiwooAddress", transfer.getNiiwooAddress());                                     //(丙方)地址
        parameterMap.put("borrowerName", transfer.getBorrowerName());                                       //借款人姓名
        parameterMap.put("borrowerNickName", transfer.getBorrowerNickName());                               //借款人昵称
        parameterMap.put("borrowerIdCard", transfer.getBorrowerIdCard());                                   //借款人身份证号/机构信用代码
        parameterMap.put("borrowEmail", transfer.getBorrowEmail());                                         //借款人邮箱
        parameterMap.put("borrowerAddress", transfer.getBorrowerAddress());                                 //借款人住址/地址
        parameterMap.put("transferName", transfer.getTransferName());                                       //出让人姓名
        parameterMap.put("transferNickName", transfer.getTransferNickName());                               //出让人昵称
        parameterMap.put("transferIdCard", transfer.getTransferIdCard());                                   //出让人身份证号
        parameterMap.put("assigneeName", transfer.getAssigneeName());                                       //受让人姓名
        parameterMap.put("assigneeNickName", transfer.getAssigneeNickName());                               //受让人昵称
        parameterMap.put("assigneeIdCard", transfer.getAssigneeIdCard());                                   //受让人身份证号码
        parameterMap.put("contractNo", transfer.getContractNo());                                           //合同编号
        parameterMap.put("projectTitle", transfer.getProjectTitle());                                       //借款用途
        parameterMap.put("repaymentType", transfer.getRepaymentType());                                     //还款方式
        parameterMap.put("receivableAmount", transfer.getReceivableAmount().toString());                    //待收本金
        parameterMap.put("capitalReceivableAmount", transfer.getCapitalReceivableAmount());                 //大写待收金额
        parameterMap.put("receivableInterest", transfer.getReceivableInterest().toString());                //应收利息
        parameterMap.put("capitalReceivableInterest", transfer.getCapitalReceivableInterest());             //大写应收利息
        parameterMap.put("transferredEffectiveDate", transfer.getTransferredEffectiveDate());               //转让生效日
        parameterMap.put("transferAmount", transfer.getTransferAmount().toString());                        //转让金额
        parameterMap.put("capitalTransferAmount", transfer.getCapitalTransferAmount());                     //大写转让金额
        parameterMap.put("originalPeriods", transfer.getOriginalPeriods());                                 //借款债权原始期限
        parameterMap.put("remainingPeriods", transfer.getRemainingPeriods());                               //借款债权剩余期限
        parameterMap.put("finalDate", transfer.getFinalDate());                                             //借款债权最终到期日
        parameterMap.put("borrowRate", transfer.getBorrowRate().toString());                                //借款债权年化利率
        parameterMap.put("serviceFeeRate", transfer.getServiceFeeRate().toString());                        //服务费率
        parameterMap.put("transferredNumber", transfer.getTransferredNumber().toString());                  //转让最大个数
        parameterMap.put("minimumTransferAmount", transfer.getMinimumTransferAmount());                     //最低转让金额
        parameterMap.put("minimumHoldPeriods", transfer.getMinimumHoldPeriods().toString());                //最小持有期数
        parameterMap.put("minimumRemainPeriods", transfer.getMinimumRemainPeriods().toString());            //最小剩余期数
        parameterMap.put("transferredLimitDay", transfer.getTransferredLimitDay().toString());              //转让限制天数
        parameterMap.put("specifiedStartTime", transfer.getSpecifiedStartTime());                           //规定转让开始时间
        parameterMap.put("specifiedEndTime", transfer.getSpecifiedEndTime());                               //规定转让结束时间
        parameterMap.put("transferLimitTime", transfer.getTransferLimitTime());                             //债权转让购买时效
        parameterMap.put("signDate", transfer.getSignDate());                                               //签署日期

        List<List<String>> invSignatureNamesList = new ArrayList<>();

        // 出让人签章
        String transferSignatureNamesText = "                出让人：" + transfer.getTransferName() + "," + transfer.getTransferIdCard();
        List<String> transferSignatureNamesCells = new ArrayList<>();
        transferSignatureNamesCells.add(transferSignatureNamesText);
        invSignatureNamesList.add(transferSignatureNamesCells);

        // 受让人签章
        String assigneeSignatureNamesText = "                受让人：" + transfer.getAssigneeName() + "," + transfer.getAssigneeIdCard();
        List<String> assigneeSignatureNamesCells = new ArrayList<>();
        assigneeSignatureNamesCells.add(assigneeSignatureNamesText);
        invSignatureNamesList.add(assigneeSignatureNamesCells);

        // 服务方签章
        String platformSignatureNamesText = "                服务方：深圳市你我金融信息服务有限公司";
        List<String> platformSignatureNamesCells = new ArrayList<>();
        platformSignatureNamesCells.add(platformSignatureNamesText);
        invSignatureNamesList.add(platformSignatureNamesCells);

        // 投资人姓名列表
        // 表格header
        List<String> headers = new ArrayList<>();
        headers.add("");

        DynamicTable signNameTable = new DynamicTable();
        signNameTable.setInsertWay(1);
        signNameTable.setKeyword("签署页：");
        signNameTable.setCellHeight(60f);
        signNameTable.setHeaders(headers);
        signNameTable.setCellVerticalAlignment(5);
        signNameTable.setDatas(invSignatureNamesList);
        signNameTable.setBorderFlag(false);

        List<DynamicTable> tables = new ArrayList<DynamicTable>();
        tables.add(signNameTable);

        dto.setDynamicTables(tables);
        dto.setParameterMap(parameterMap);

        generateContract(dto);
        logger.info("债权转让协议生成结束... creditorSaleDetailId:{}", creditorSaleDetail.getId());
    }

    private ProjectContract signContract(String contractId, CreditorSaleDetail creditorSaleDetail, String investorUserId,
                                         CreditorTransferProtocolPreviewResponseDTO transfer, FadadaContractTemplateFile contractTemplate) throws Exception {
        String METHOD_NAME = "法大大合同自动签署-债权转让协议 creditorSaleDetailId:" + creditorSaleDetail.getId();
        logger.info(METHOD_NAME);

        // 授权信息(CA证书编号)
        UserAuthorizationInfoResponseDTO transferUserAuthorizationInfo = userAuthorizationInfoDubboService
                .getUserAuthorizationInfo(creditorSaleDetail.getUserId());
        UserAuthorizationInfoResponseDTO assigneeUserAuthorizationInfo = userAuthorizationInfoDubboService
                .getUserAuthorizationInfo(investorUserId);

        String transactionId = null;
        FadadaResponseDTO fadadaResponse = null;
        String docTitle = "债权转让协议_" + contractId;

        // 出让人签署
        transactionId = snowflakeIdWorker.nextId() + "";
        String transferCaCertId = transferUserAuthorizationInfo.getFadadaCacertId();
        String transferSignKeyword = "出让人：" + transfer.getTransferName();
        fadadaResponse = extSignAuto(transactionId, contractId, transferCaCertId,
                SignClientRoleEnum.GUARANTEE.getValue(), docTitle, transferSignKeyword);
        logger.info("法大大合同自动签署-债权转让协议 出让人签署结束... creditorSaleDetailId:{}", creditorSaleDetail.getId());

        // 受让人签署
        transactionId = snowflakeIdWorker.nextId() + "";
        String assigneeCaCertId = assigneeUserAuthorizationInfo.getFadadaCacertId();
        String assigneeSignKeyword = "受让人：" + transfer.getAssigneeName();
        fadadaResponse = extSignAuto(transactionId, contractId, assigneeCaCertId,
                SignClientRoleEnum.BORROWER.getValue(), docTitle, assigneeSignKeyword);
        logger.info("法大大合同自动签署-债权转让协议 受让人签署结束... creditorSaleDetailId:{}", creditorSaleDetail.getId());

        // 平台公章
        transactionId = snowflakeIdWorker.nextId() + "";
        String platformSignKeyword = "服务方：深圳市你我金融信息服务有限公司";
        fadadaResponse = extSignAuto(transactionId, contractId, platformCaCertId,
                SignClientRoleEnum.PLATFORM.getValue(), docTitle, platformSignKeyword);
        logger.info("法大大合同自动签署-债权转让协议 平台签署结束... creditorSaleDetailId:{}", creditorSaleDetail.getId());

        return this.buildContractUpdateRecord(contractTemplate.getTemplateId(), contractId, transactionId,
                fadadaResponse.getViewUrl(), fadadaResponse.getDownloadUrl());
    }


}
